# -*- coding: utf-8 -*-
"""
@Time    : 2024/7/11 18:21 
@Author  : ZhangShenao 
@File    : blocking_crawler.py
@Desc    : 异步非阻塞爬虫

asyncio库中,包含了大量操作协程相关的工具
"""
import asyncio

from bacis.decorator.perf_log_decorator import perf_log


# 使用async关键字,声明异步函数
async def crawl_page(url: str) -> None:
    """
    异步执行,爬取单个页面
    :param url: 页面url
    """
    print(f'crawling {url} ...')

    # await是阻塞调用,会等待协程执行完成
    await asyncio.sleep(float(url.split('-')[-1]))
    print(f'finish crawling {url}')


async def crawl_pages(urls: list) -> None:
    """
    异步执行,爬取多个页面
    :param urls: 页面url列表
    """

    # 创建异步任务
    tasks = [asyncio.create_task(crawl_page(url)) for url in urls]

    # 并行执行任务
    # for task in tasks:
    #     # 阻塞等待任务执行完成
    #     await task

    # 等价于下面这种写法
    # *list操作是解包列表,将列表变成了函数的参数
    # 与之对应的是,**dict是将字典变成了函数的参数
    await asyncio.gather(*tasks)


@perf_log
def main():
    pages = [f'url-{x}' for x in range(1, 5)]

    # 使用asyncio.run执行异步函数
    asyncio.run(crawl_pages(pages))


main()
